/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


/*************************************************************************
 * File: network.h
 *************************************************************************
 *\author: starlove
 *************************************************************************/

#ifndef __MLSE_NETWORK_NETWORK_H__
#define	__MLSE_NETWORK_NETWORK_H__

#include <network/event.h>
#include <platform/buffer.h>
#include <codec/exdata_wrapper.h>

typedef CAutoExpandBuffer<__MLSE_AUTOBUFFER_DEFSIZE__> NETWORKBUFFER;
typedef NETWORKBUFFER *LPNETWORKBUFFER;

enum enumPacketFlag
{
    ePF_NORMAL			= 0
    ,ePF_COMPRESS		= 0x1
    ,ePF_ENCRYPT		= 0x1 << 1
    ,ePF_ENCODE 		= 0x1 << 2
};

enum enumPeerDataType
{
	ePEERDTP_PACKET 	= 0,
	ePEERDTP_JSON 		= 1,
	ePEERDTP_HTTP_JSON 	= 2,
	ePEERDTP_HTTP 		= 3
};
#pragma pack(1)
typedef struct _PACKET_BASE_HEADER
{
    unsigned short verifiymask;
    unsigned short flag;
} PACKET_BASE_HEADER, *LPPACKET_BASE_HEADER;

typedef struct _PACKET_FIXED_HEADER
{
	_PACKET_BASE_HEADER base;
    unsigned int zclength;
    unsigned int length;
} PACKET_FIXED_HEADER, *LPPACKET_FIXED_HEADER;

typedef struct __PACKET
{
    PACKET_FIXED_HEADER header;
    __PACKET(){ header.base.flag = 0; }
    void *GetData(){return (char *)this + sizeof(__PACKET);};
    void UnPack(LPNETWORKBUFFER p_outbuf);
    void Pack(LPNETWORKBUFFER p_outbuf, char *buf, unsigned int size);
} PACKET, *LPPACKET;

typedef struct __HTTP_ACTION
{
	char ver;
	char tp;
	char url[255];
	char qs[255];
}HTTP_ACTION, *LPHTTP_ACTION;

typedef struct __HTTPRESPONSE
{
	char status_code[255];
	CMapWrapper header;
}HTTPRESPONSE, *LPHTTPRESPONSE;
#pragma pack()

class INetwork
{
public:
    virtual ~INetwork() {};
    virtual bool Init() = 0;
    virtual bool Destory() = 0;
protected:
private:
};

class IPeer : public IEventProcessor
{
public:
    virtual ~IPeer() {};
    virtual void Destory() = 0;
    virtual bool Connect(const char *, unsigned int) = 0;
    virtual NETWORKBUFFER *GetRecvBuffer() = 0;
    virtual NETWORKBUFFER *GetSendBuffer() = 0;
    virtual unsigned int OnWriteReady(unsigned int ) = 0;
    virtual void OnReadReady(LPPACKET) = 0;
    virtual void OnError() = 0;
    virtual void OnEvent(LPEVENT, int) = 0;
    virtual HANDLE GetIOHandle() = 0;
    virtual int GetId() = 0;
    virtual int SendData(char *, unsigned int) = 0;
    virtual int RecvData() = 0;
    virtual void SetDataType(char c) = 0;
    virtual void ProcessHttpRequest(CMapWrapper *, LPHTTPRESPONSE, LPNETWORKBUFFER) = 0;
};

class IService : public IEventProcessor
{
public:
    virtual ~IService() {};
    virtual bool Create(const char *, unsigned int, unsigned int) = 0;
    virtual void Destory() = 0;
    virtual void OnConnected(SOCKET, sockaddr *, sockaddr *, IPeer *&) = 0;
    virtual void OnWriteReady(SOCKET) = 0;
    virtual void OnReadReady(SOCKET) = 0;
    virtual void OnError(SOCKET) = 0;
    virtual void OnEvent(LPEVENT, int) = 0;
protected:
private:
};

class ISocket
{
public:
    virtual ~ISocket() {};
    virtual bool Init(CEventDispatcher *) = 0;
    virtual bool Destory() = 0;
    virtual void Accept(SOCKET, IEventProcessor *) = 0;
    virtual void BindProcessor(IEventProcessor *) = 0;
    virtual void BindIO(SOCKET) = 0;
    virtual SOCKET Connect(const char *, unsigned int) = 0;
    virtual SOCKET Listen(unsigned int, const char *) = 0;
    virtual void GetSockAddr(LPEVENT, sockaddr *, sockaddr *) = 0;
    virtual void Close(SOCKET) = 0;
    virtual void Close(LPEVENT) = 0;
    virtual int Send(SOCKET &, void *, unsigned int) = 0;
    virtual int Recv(SOCKET &, void *, unsigned int) = 0;
    virtual int IORecv(SOCKET, IPeer *, IEventProcessor *) = 0;
    virtual int IOSend(SOCKET, IPeer *, IEventProcessor *) = 0;
    virtual IEventIO *GetEventIO() = 0;
protected:
private:
};

extern std::map<SOCKET, IPeer *> g_peers;
extern bool RegisterPeer(IPeer *pPeer);
extern void UnRegisterPeer(IPeer *pPeer);
#endif
